#include "protocol.h"
#include "client.h"

static int lsPacket(char *optName)
{
	int i = 0;
	int pkg_len = 8;
	/* 包头 */
	optName[i++] = 0xC0;
	
	/* pkg_len */
	optName[i++] = pkg_len & 0xff;
	optName[i++] = pkg_len >> 8 & 0xff;
	optName[i++] = pkg_len >> 16 & 0xff;
	optName[i++] = pkg_len >> 24 & 0xff;

	/* cmd_len */
	enum CMD_NO cmd_no = FTP_CMD_LS;
	optName[i++] = cmd_no & 0xff;
	optName[i++] = cmd_no >> 8 & 0xff;
	optName[i++] = cmd_no >> 16 & 0xff;
	optName[i++] = cmd_no >> 24 & 0xff;

	/* 包尾 */
	optName[i++] = 0xC0;
	optName[i] = '\0';
}

static int unpack(char *recvbuff)
{
	u_int8_t ch;
	int i = 0;
	u_int8_t destOpt[BUFFSIZE] = {0};
	
	/* 读取到包头 */
	do
	{
		ch = recvbuff[i++];
	
	}while (ch != 0xC0);
	
	/* 为防止读到错误的包头*/
	while (ch == 0xC0)
	{
		ch = recvbuff[i++];
	}

	int k = 0;
	
	/* 解析真正内容 @pkg_len:内容长度 @cmd_no:请求命令*/
	while (ch != 0xC0)
	{
		destOpt[k++] = ch;
		ch = recvbuff[i++];
	}
	destOpt[k] = '\0';

	i = 0;
	int pkg_len = destOpt[i++] | destOpt[i++] << 8 | destOpt[i++] << 16 | destOpt[i++] << 24;
	if (pkg_len != k)
	{
		fprintf(stderr, "faild\n");
		exit(1);
	}
	int cmd_no = destOpt[i++] | destOpt[i++] << 8 | destOpt[i++] << 16 | destOpt[i++] << 24;
	int resp_len = destOpt[i++] | destOpt[i++] << 8 | destOpt[i++] << 16 | destOpt[i++] << 24;
	if (destOpt[i++] != 0)
	{
		fprintf(stderr, "faild\n");
		exit(1);
	}
	puts(&destOpt[i]);
	return 0;
}

int getPacket(struct FSM_ST *fsm)
{
	if (strcmp(fsm->optbuff, "ls") == 0)
	{
		fsm->cmd_no = FTP_CMD_LS;
		lsPacket(fsm->sendbuff);
	}
//	else if ()
	else
		return -1;
	return 0;
}

void driver(struct FSM_ST fsm)
{
	switch (fsm->state)
	{
		case FSM_IN:
			if (fgets(fsm->optbuff, BUFFSIZE, stdin) == NULL)
			{
				fsm->errstr = "fgets()";
				fsm->state = FSM_EX;
			}
			else
			{
				fsm->state = FSM_PACKET;
			}
			break;
		case FSM_PACKET:
			if (getPacket(&fsm) < 0)
			{
				fsm->errstr = "getPacket()";
				fsm->state = FSM_EX;
			}
			else
			{
				fsm->state = FSM_SEND;
			}
			break;
		case FSM_SEND:
			if (send(fsm->confd, fsm->sendbuff, BUFFSIZE, 0) < 0)
			{
				fsm->errstr = "send()";
				fsm->state = FSM_EX;
			}
			else
			{
				fsm->state = FSM_RECV;
			}
			break;
		case FSM_RECV:
			if (recv(fsm->confd, fsm->recvbuff, BUFFSIZE, 0) < 0)
			{
				fsm->errstr = "recv()";
				fsm->state = FSM_EX;
			}
			else
				fsm->state = FSM_UNPC;
			break;
		case FSM_UNPC:
			if (unpack(fsm) < 0)
			{
				fsm->errstr = "unpack()";
				fsm->state = FSM_EX;
			}
			else
				fsm->state = FSM_OUT;
			break;
		case FSM_OUT:
			if (fsm->cmd_no == FTP_CMD_LS)
				puts(fsm->outbuff);
			fsm->state = FSM_IN;
			break;
		case FSM_CANCEL:
			break;
		case FSM_EX:
			break;
		case FSM_T:
			break;
		default:
			break;
	}

}

int main(int argc, char **argv)
{
	if (argc < 3)
	{
		fprintf(stderr, "Usage:\n");
		exit(1);
	}
	/* 创建一个套接字 */
	int sockfd = socket(AF_INET, SOCK_STREAM, 0);	
	if (sockfd < 0)
	{
		perror("socket()");
		exit(1);
	}
	
	struct sockaddr_in server;
	server.sin_family = AF_INET;
	server.sin_port = htons(atoi(argv[2]));
	inet_pton(AF_INET, argv[1], &server.sin_addr);
	
	/* 连接服务端 */
	if (connect(sockfd, (struct sockaddr *)&server, sizeof(server)) < 0)
	{
		perror("connect()");
		exit(1);
	}
	while (1)
	{
		struct FSM_ST fsm;
		fsm.state = FSM_IN;
		fsm.confd = socket;
		driver(&fsm);
		u_int8_t sendbuff[BUFFSIZE] = {0};
		u_int8_t recvbuff[BUFFSIZE] = {0};
		lsPacket(sendbuff);

		recv(sockfd, recvbuff, BUFFSIZE, 0);
		unpack(recvbuff);
		memset(sendbuff, 0, BUFFSIZE);
		memset(recvbuff, 0, BUFFSIZE);
		sleep(1);
	}
	
	exit(0);
}
